using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Threading;

namespace SerialPortCommunicationProject.Tools
{
    public enum Status
    {
        Receive,
        Send
    }

    class ViewModelHelper
    {
        static string msg;
        public static RichTextBox RTBox;
        public static TextBox TBox;
        public static Button BtnSwitch;
        public static string[] EncodingHere=new string[2];
        public static ObservableCollection<string> LstClient;
        public static ComboBox CBboxCientsIp;
        public static TextBlock CommunicationStatus;
        private static ICommunication comm;
        public static void SetComm(ICommunication com)
        {
            comm = com;
        }
        public static string Msg { get; set; }

        public static void SetEncoding(DeviceSelectWindow w)
        {
            if (w.Panel_Normal.Visibility == Visibility.Visible)
            {
                if (w.ReceiveSetting_Hex.IsChecked == true)
                {
                    EncodingHere[0] = "HEX";
                }
                else if (w.ReceiveSetting_ASCII.IsChecked == true)
                {
                    EncodingHere[0] = "ASCII";
                }

                if (w.SendSetting_Hex.IsChecked == true)
                {
                    EncodingHere[1] = "HEX";
                }
                else if (w.SendSetting_ASCII.IsChecked == true)
                {
                    EncodingHere[1] = "ASCII";
                }
            }else if(w.Panel_DeviceSelect.Visibility == Visibility.Visible)
            {
                EncodingHere[0] = EncodingHere[1] = App.CurrentDevice?.Encoding;
            }
        }

        public static void GenerateDataRecord(ICommunication comm, Status status, EndPoint remotePe = null)
        {
            string statusString = "# RECV";
            string encoding = EncodingHere[0];
            if (status == Status.Receive)
            {
                statusString = "# RECV";
                encoding = EncodingHere[0];
                msg = ConverterString(comm.ReceiveBuffer, encoding);
            }
            else if (status == Status.Send)
            {
                statusString = "# SEND";
                encoding = EncodingHere[1];
                msg = ConverterString(comm.SendBuffer, encoding);
            }

            RTBox.Dispatcher.Invoke(() =>
            {
                if (msg == null)
                {
                    if (comm != null && comm is SocketTcpClientCommunication)
                    {
                        //如果是client
                        comm.Close();
                    }
                    return;
                }
                Tool.ConsoleBox console = new Tool.ConsoleBox(RTBox);
                //[2021 - 12 - 16 15:33:19.681]# RECV ASCII>
                string assistText = $"[{DateTime.Now}] {statusString} {encoding} ";
                if (remotePe != null)
                {
                    assistText += $"FROM {remotePe.ToString()}";
                }
                assistText += "> ";
                console.AssistText(assistText);
                if (status == Status.Send)
                {
                    console.DataSend($"{msg}\n");
                }
                else if (status == Status.Receive)
                {
                    console.DataText($"{msg}\n");
                }
                msg = null;
                RTBox.ScrollToEnd();

            });
        }

        public static void ShowJustConnectedClient(EndPoint pe)
        {
            RTBox.Dispatcher.Invoke(() =>
            {
                Tool.ConsoleBox console = new Tool.ConsoleBox(RTBox);
                //[2021-12-17 14:26:01.039]#Client 192.168.11.44:60796 gets online.
                console.AssistText($"[{DateTime.Now}]# Client {pe.ToString()} -- Connected ");
                RTBox.ScrollToEnd();
            });
        }

        public static void ShowJustDisConnectedClient(EndPoint pe)
        {
            RTBox.Dispatcher.Invoke(() =>
            {
                Tool.ConsoleBox console = new Tool.ConsoleBox(RTBox);
                //[2021-12-17 14:26:01.039]#Client 192.168.11.44:60796 gets online.
                console.AssistText($"[{DateTime.Now}]# Client {pe.ToString()} -- DisConnected ");
                RTBox.ScrollToEnd();
            });
        }

        public static void UpdateClientsIp(int count)
        {
            CBboxCientsIp.Dispatcher.Invoke(() =>
            {
                LstClient.Clear();
                if (comm is SocketTcpServerCommunication)
                {
                    SocketTcpServerCommunication server = comm as SocketTcpServerCommunication;
                    for (int i = 0; i < server.ListeningList.Count; i++)
                    {
                        string temp = server.ListeningList[i]?.RemoteEndPoint.ToString();
                        LstClient.Add(temp);
                    }
                }
                LstClient.Insert(0, $"All Connections({count})");
                CBboxCientsIp.ItemsSource = LstClient;
                CBboxCientsIp.SelectedIndex = 0;
                
            });
        }

        private static string ConverterString(byte[] buffer, string encoding)
        {
            if (buffer.Length == 0)
            {
                return null;
            }
            string msg = null;
            
            if (encoding == "HEX")
            {
                msg = BitConverter.ToString(buffer, 0).Replace('-',' ').ToUpper();
            }else if (encoding == "ASCII")
            {
                msg = Encoding.ASCII.GetString(buffer);
            }
            return msg;
        }
        public static int SelectedIPEndPointIndex { get; set; }
    }
}
